package com.sneakxy.mybatis.commons.repository.support;

import java.lang.reflect.Method;
import java.util.Iterator;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.repository.query.Parameter;
import org.springframework.data.repository.query.QueryMethod;
import org.springframework.data.repository.query.RepositoryQuery;

import com.sneakxy.mybatis.commons.orm.MybatisEntityManager;
import com.sneakxy.mybatis.commons.repository.query.MybatisQueryMethod;
import com.sneakxy.mybatis.commons.repository.query.parser.MybatisCommonsParamNameResolver;

/**
 * @author 潜行的青衣
 */
public abstract class AbstractMybatisRepositoryQuery implements RepositoryQuery, InitializingBean {

	private MybatisQueryMethod queryMethod;
	
	private MybatisEntityManager entityManager;
	
	private MybatisCommonsParamNameResolver resolver;
	
	public AbstractMybatisRepositoryQuery(
			MybatisEntityManager entityManager,
			MybatisQueryMethod queryMethod) {
		this.queryMethod = queryMethod;
		this.entityManager = entityManager;
		this.resolver = new MybatisCommonsParamNameResolver(
				this.getEntityManager().getConfiguration(), this.getMethod());
	}
	
	protected Object createParameterObject(Object[] parameters, boolean isPageCount) {
		return resolver.getNamedParams(parameters, isPageCount);
	}

	private void createPageCountQuery() {
		if(this.getQueryMethod().isPageQuery() || this.getQueryMethod().isSliceQuery()) {
			doCreatePageCountQuery();
		}
	}
	
	protected String createStatementId(String name) {
		StringBuilder idBuilder = new StringBuilder().append(name);
		Iterator<?> it = this.getQueryMethod().getParameters().iterator();
		Parameter parameter = null;
		while(it.hasNext()) {
			parameter = (Parameter) it.next();
			idBuilder.append("-");
			idBuilder.append(parameter.getType().getSimpleName());
		}
		return idBuilder.toString();
	}
	
	@Override
	public void afterPropertiesSet() throws Exception {
		this.createPageCountQuery();
	}

	protected abstract void doCreatePageCountQuery();
	
	public MybatisEntityManager getEntityManager() {
		return this.entityManager;
	}
	
	public Method getMethod() {
		return this.queryMethod.getQueryMethod();
	}

	@Override
	public QueryMethod getQueryMethod() {
		return this.queryMethod;
	}
	
}
